home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / comp / dup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-15  |  10.3 KB  |  447 lines  |  [TEXT/ttxt]

  1. /**********************************************************************\
  2. *
  3. *  Copyright (c) 1994  Carnegie Mellon University
  4. *  All rights reserved.
  5. *  
  6. *  Use and copying of this software and preparation of derivative
  7. *  works based on this software are permitted, including commercial
  8. *  use, provided that the following conditions are observed:
  9. *  
  10. *  1. This copyright notice must be retained in full on any copies
  11. *     and on appropriate parts of any derivative works.
  12. *  2. Documentation (paper or online) accompanying any system that
  13. *     incorporates this software, or any part of it, must acknowledge
  14. *     the contribution of the Gwydion Project at Carnegie Mellon
  15. *     University.
  16. *  
  17. *  This software is made available "as is".  Neither the authors nor
  18. *  Carnegie Mellon University make any warranty about the software,
  19. *  its performance, or its conformity to any specification.
  20. *  
  21. *  Bug reports, questions, comments, and suggestions should be sent by
  22. *  E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  23. *
  24. ***********************************************************************
  25. *
  26. * $Header: dup.c,v 1.6 94/10/05 20:54:30 nkramer Exp $
  27. *
  28. * This file duplicates parts of the parse tree.
  29. *
  30. \**********************************************************************/
  31.  
  32. #include "../compat/std-c.h"
  33.  
  34. #include "mindycomp.h"
  35. #include "src.h"
  36. #include "literal.h"
  37. #include "free.h"
  38. #include "lose.h"
  39. #include "dup.h"
  40.  
  41.  
  42. /* Utilities. */
  43.  
  44. #if 0
  45. static struct param_list *dup_params(struct param_list *params)
  46. {
  47.     struct param_list *res = make_param_list();
  48.     struct param *param, **param_ptr;
  49.  
  50.     param_ptr = &res->required_params;
  51.     for (param = params->required_params; param != NULL; param = param->next) {
  52.     struct expr *type = param->type ? dup_expr(param->type) : NULL;
  53.     struct param *new = make_param(dup_id(param->id), type);
  54.     *param_ptr = new;
  55.     param_ptr = &new->next;
  56.     }
  57.     *param_ptr = NULL;
  58.  
  59.     if (params->next_param)
  60.     res->next_param = dup_id(params->next_param);
  61.     if (params->rest_param)
  62.     res->rest_param = dup_id(params->rest_param);
  63.  
  64.     if (params->allow_keys) {
  65.     struct keyword_param *key;
  66.  
  67.     res->allow_keys = TRUE;
  68.     for (key = params->keyword_params; key != NULL; key = key->next) {
  69.         struct expr *type = key->type ? dup_expr(key->type) : NULL;
  70.         struct expr *def = key->def ? dup_expr(key->def) : NULL;
  71.         struct keyword_param *new
  72.         = make_keyword_param(key->keyword, dup_id(key->id), type, def);
  73.         add_keyword_param(res, new);
  74.     }
  75.     }
  76.  
  77.     return res;
  78. }
  79.  
  80. static struct bindings *dup_bindings(struct bindings *bindings)
  81. {
  82.     return make_bindings(dup_params(bindings->params),
  83.              bindings->expr ? dup_expr(bindings->expr) : NULL);
  84. }
  85.  
  86. static struct return_type_list *dup_rettypes(struct return_type_list *rettypes)
  87. {
  88.     struct return_type_list *res = make_return_type_list();
  89.     struct return_type *r, *new;
  90.  
  91.     for (r = rettypes->req_types; r != NULL; r = next) {
  92.     new = malloc(sizeof(*new));
  93.     new->type = r->type ? dup_expr(r->type) : NULL;
  94.     new->temp = r->temp;
  95.     *nes->req_types_tail = new;
  96.     nes->req_types_tail = &new->next;
  97.     }
  98.     *req_types_tail = NULL;
  99.  
  100.     if (rettypes->req_types_list)
  101.     res->req_types_list = dup_expr(rettypes->req_types_list);
  102.     if (rettypes->rest_type)
  103.     res->rest_type = dup_expr(rettypes->rest_type);
  104.  
  105.     return res;
  106. }
  107.  
  108. static void dup_plist(struct plist *plist)
  109. {
  110.     struct plist *res = make_property_list();
  111.     struct property *prop, *new;
  112.  
  113.     for (prop = plist->head; prop != NULL; prop = prop->next) {
  114.     new = malloc(sizeof(*new));
  115.     new->keyword = prop->keyword;
  116.     new->expr = dup_expr(prop->expr);
  117.     *res->tail = new;
  118.     res->tail = &new->next;
  119.     }
  120.     *res->tail = NULL;
  121.  
  122.     return res;
  123. }
  124.  
  125. static struct condition_body *dup_condition_body(struct condition_body *body)
  126. {
  127.     if (body) {
  128.     struct condition_body *res = malloc(sizeof(*res));
  129.     struct condition *cond, **prev;
  130.  
  131.     res->clause = malloc(sizeof(*res->clause));
  132.     prev = &res->clause->conditions;
  133.     for (cond = body->clause->conditions; cond!=NULL; cond = cond->next) {
  134.         struct condition *new = malloc(sizeof(*new));
  135.         new->cond = dup_expr(cond->expr);
  136.         *prev = new;
  137.         prev = &new->next;
  138.     }
  139.     *prev = NULL;
  140.     res->clause->body = dup_body(body->clause->body);
  141.  
  142.     res->next = dup_condition_body(body->next);
  143.  
  144.     return res;
  145.     }
  146.     else
  147.     return NULL;
  148. }
  149.  
  150. static struct method *dup_method(struct method *method)
  151. {
  152.     struct method *res
  153.     = make_method_description(dup_params(method->params),
  154.                   dup_rettypes(method->rettypes),
  155.                   dup_body(method->body));
  156.     if (method->name)
  157.     res->name = dup_id(method->name);
  158.     if (method->debug_name)
  159.     res->debug_name = dup_literal(method->debug_name);
  160.     if (method->specializers)
  161.     res->specializers = dup_expr(method->specializers);
  162.  
  163.     return res;
  164. }
  165. #endif
  166.  
  167.  
  168. /* Stuff to dup expressions. */
  169.  
  170. static struct expr *dup_varref_expr(struct varref_expr *e)
  171. {
  172.     return make_varref(dup_id(e->var));
  173. }
  174.  
  175. static struct expr *dup_literal_expr(struct literal_expr *e)
  176. {
  177.     return make_literal_ref(dup_literal(e->lit));
  178. }
  179.  
  180. static struct expr *dup_call_expr(struct call_expr *e)
  181. {
  182.     struct arglist *args = make_argument_list();
  183.     struct argument *arg;
  184.     struct expr *func = dup_expr(e->func);
  185.  
  186.     if (func == NULL)
  187.     return NULL;
  188.  
  189.     for (arg = e->args; arg != NULL; arg = arg->next) {
  190.     struct expr *new = dup_expr(arg->expr);
  191.     if (new == NULL) {
  192.         free_expr(make_function_call(func, args));
  193.         return NULL;
  194.     }
  195.     add_argument(args, make_argument(new));
  196.     }
  197.     return make_function_call(func, args);
  198. }
  199.  
  200. static struct expr *dup_method_expr(struct method_expr *e)
  201. {
  202.     return NULL;
  203. #if 0
  204.     return make_method_ref(dup_method(e->method));
  205. #endif
  206. }
  207.  
  208. static struct expr *dup_dot_expr(struct dot_expr *e)
  209. {
  210.     struct expr *arg, *func;
  211.  
  212.     if ((arg = dup_expr(e->arg)) == NULL)
  213.     return NULL;
  214.     if ((func = dup_expr(e->func)) == NULL) {
  215.     free_expr(arg);
  216.     return NULL;
  217.     }
  218.  
  219.     return make_dot_operation(arg, func);
  220. }
  221.  
  222. static struct expr *dup_body_expr(struct body_expr *e)
  223. {
  224.     struct body *new = dup_body(e->body);
  225.  
  226.     if (new == NULL)
  227.     return NULL;
  228.     else
  229.     return make_body_expr(new);
  230. }
  231.  
  232. #if 0
  233. static void dup_exception_clauses(struct exception_clause *clauses)
  234. {
  235.     struct exception_clause *clause, *next;
  236.  
  237.     lose("###");
  238.  
  239.     for (clause = clauses; clause != NULL; clause = next) {
  240.     dup_expr(clause->type);
  241.     if (clause->condition)
  242.         dup_id(clause->condition);
  243.     dup_plist(clause->plist);
  244.     dup_body(clause->body);
  245.     next = clause->next;
  246.     dup(clause);
  247.     }
  248. }
  249. #endif
  250.  
  251. static struct expr *dup_block_expr(struct block_expr *e)
  252. {
  253.     return NULL;
  254. #if 0
  255.     struct block_expr *res
  256.     = (struct block_expr *)make_block(e->line,
  257.                       NULL,
  258.                       dup_body(e->body),
  259.                       NULL);
  260.  
  261.     if (e->exit_fun)
  262.     res->exit_fun = dup_id(e->exit_fun);
  263.     res->inner = dup_exception_clauses(e->inner);
  264.     if (e->cleanup)
  265.     res->cleanup = dup_body(e->cleanup);
  266.     res->outer = dup_exception_clauses(e->outer);
  267.  
  268.     return (struct expr *)res;
  269. #endif
  270. }
  271.  
  272. static struct expr *dup_case_expr(struct case_expr *e)
  273. {
  274.     return NULL;
  275. #if 0
  276.     return make_case(dup_condition_body(e->body));
  277. #endif
  278. }
  279.  
  280. static struct expr *dup_if_expr(struct if_expr *e)
  281. {
  282.     struct expr *cond;
  283.     struct body *consequent;
  284.     struct body *alternate;
  285.  
  286.     if ((cond = dup_expr(e->cond)) == NULL)
  287.     return NULL;
  288.     if ((consequent = dup_body(e->consequent)) == NULL) {
  289.     free_expr(cond);
  290.     return NULL;
  291.     }
  292.     if ((alternate = dup_body(e->alternate)) == NULL) {
  293.     free_expr(cond);
  294.     free_body(consequent);
  295.     return NULL;
  296.     }
  297.     return make_if(cond, consequent, make_else(e->else_line, alternate));
  298. }
  299.  
  300. static struct expr *dup_for_expr(struct for_expr *e)
  301. {
  302.     return NULL;
  303. #if 0
  304.     struct for_clause *clause, *next;
  305.  
  306.     lose("###");
  307.  
  308.     for (clause = e->clauses; clause != NULL; clause = next) {
  309.     dup_params(clause->vars);
  310.     switch (clause->kind) {
  311.       case for_EQUAL_THEN:
  312.         {
  313.         struct equal_then_for_clause *c
  314.             = (struct equal_then_for_clause *)clause;
  315.         dup_expr(c->equal);
  316.         dup_expr(c->then);
  317.         break;
  318.         }
  319.       case for_IN:
  320.         {
  321.         struct in_for_clause *c = (struct in_for_clause *)clause;
  322.         dup_expr(c->collection);
  323.         break;
  324.         }
  325.       case for_FROM:
  326.         {
  327.         struct from_for_clause *c = (struct from_for_clause *)clause;
  328.         dup_expr(c->from);
  329.         if (c->to)
  330.             dup_expr(c->to);
  331.         if (c->by)
  332.             dup_expr(c->by);
  333.         }
  334.     }
  335.     next = clause->next;
  336.     dup(clause);
  337.     }
  338.     if (e->until)
  339.     dup_expr(e->until);
  340.     dup_body(e->body);
  341.     if (e->finally)
  342.     dup_body(e->finally);
  343.     dup(e);
  344. #endif
  345. }
  346.  
  347. static struct expr *dup_select_expr(struct select_expr *e)
  348. {
  349.     return NULL;
  350. #if 0
  351.     return make_select(dup_expr(e->expr),
  352.                e->by ? dup_expr(e->by) : NULL,
  353.                dup_condition_body(e->body));
  354. #endif
  355. }
  356.  
  357. static struct expr *dup_varset_expr(struct varset_expr *e)
  358. {
  359.     struct expr *value = dup_expr(e->value);
  360.  
  361.     if (value != NULL)
  362.     return make_varset(dup_id(e->var), value);
  363.     else
  364.     return NULL;
  365. }
  366.  
  367. static struct expr *dup_binop_series_expr(struct binop_series_expr *e)
  368. {
  369.     return NULL;
  370. }
  371.  
  372. static struct expr *dup_loop_expr(struct loop_expr *e)
  373. {
  374.     return NULL;
  375. #if 0
  376.     return make_loop(dup_body(e->body));
  377. #endif
  378. }
  379.  
  380. static struct expr *dup_repeat_expr(struct repeat_expr *e)
  381. {
  382.     return NULL;
  383. #if 0
  384.     return make_repeat();
  385. #endif
  386. }
  387.  
  388. static struct expr *dup_error_expr(struct expr *e)
  389. {
  390.     return NULL;
  391. #if 0
  392.     return make_error_expr();
  393. #endif
  394. }
  395.  
  396. static struct expr *(*ExprDuprs[(int)expr_Kinds])() = {
  397.     dup_varref_expr, dup_literal_expr, dup_call_expr,
  398.     dup_method_expr, dup_dot_expr, dup_body_expr, dup_block_expr,
  399.     dup_case_expr, dup_if_expr, dup_for_expr, dup_select_expr,
  400.     dup_varset_expr, dup_binop_series_expr, dup_loop_expr,
  401.     dup_repeat_expr, dup_error_expr
  402. };
  403.  
  404. struct expr *dup_expr(struct expr *e)
  405. {
  406.     return (*ExprDuprs[(int)e->kind])(e);
  407. }
  408.  
  409.  
  410. /* Stuff to dup constituents. */
  411.  
  412. struct constituent *dup_constituent(struct constituent *c)
  413. {
  414.     if (c->kind == constituent_EXPR) {
  415.     struct expr *expr = dup_expr(((struct expr_constituent *)c)->expr);
  416.  
  417.     if (expr == NULL)
  418.         return NULL;
  419.     else
  420.         return make_expr_constituent(expr);
  421.     }
  422.     else
  423.     return NULL;
  424. }
  425.  
  426. struct body *dup_body(struct body *body)
  427. {
  428.     struct body *res = make_body();
  429.     struct constituent *ptr, **prev;
  430.  
  431.     prev = &res->head;
  432.  
  433.     for (ptr = body->head; ptr != NULL; ptr = ptr->next) {
  434.     struct constituent *new = dup_constituent(ptr);
  435.     if (new == NULL) {
  436.         *prev = NULL;
  437.         free_body(res);
  438.         return NULL;
  439.     }
  440.     *prev = new;
  441.     prev = &new->next;
  442.     }
  443.     *prev = NULL;
  444.  
  445.     return res;
  446. }
  447.